/* 
*  Copyright (C) 2009-2010 WCG Project
*
*  This program is free software; you can redistribute it and/or modify it
*  under the terms of the GNU General Public License as published by the
*  Free Software Foundation; either version 2 of the License, or (at
*  your option) any later version.
*
*  This program is distributed in the hope that it will be useful, but
*  WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
*  General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with this program; if not, write to the Free Software Foundation,
*  Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*  In addition, as a special exception, the author gives permission to
*  link the code of this program with the Half-Life Game Engine ("HL
*  Engine") and Modified Game Libraries ("MODs") developed by Valve,
*  L.L.C ("Valve"). You must obey the GNU General Public License in all
*  respects for all of the code used other than the HL Engine and MODs
*  from Valve. If you modify this file, you may extend this exception
*  to your version of the file, but you are not obligated to do so. If
*  you do not wish to do so, delete this exception statement from your
*  version.
*/


new const Float:p_quickness[5]			= {0.02, 0.03, 0.05, 0.06, 0.08}		// Quickness
new const Float:p_thorns[5]				= {0.03, 0.06, 0.09, 0.12, 0.15}		// Thorns Aura
new const Float:p_trueshot[5]			= {0.15, 0.20, 0.25, 0.30, 0.35}		// Trueshot Aura
new const p_tranquility[5]				= {2, 4, 6, 8, 10}						// Tranquility
new const p_tranquility_manacost[5]		= {16, 22, 28, 36, 40}


DRUID_InitSkills()
{
	SM_InitSkill( SKILL_QUICKNESS, CLASS_DRUID, SKILL_TYPE_TRAINABLE, sizeof(p_quickness) )
	SM_InitSkill( SKILL_THORNS, CLASS_DRUID, SKILL_TYPE_TRAINABLE, sizeof(p_thorns) )
	SM_InitSkill( SKILL_TRUESHOT, CLASS_DRUID, SKILL_TYPE_TRAINABLE, sizeof(p_trueshot) )
	SM_InitSkill( ABILITY_TRANQUILITY, CLASS_DRUID, SKILL_TYPE_ABILITY, sizeof(p_tranquility), 20, 15 )
	SM_InitSkill( ULTIMATE_ENTANGLE, CLASS_DRUID, SKILL_TYPE_ULTIMATE, 1, 10, 15 )
}


//------------------------------------
// DRUID_TriggerAbility
//
//------------------------------------
DRUID_TriggerAbility( id, iSkillID )
{
	if( iSkillID == ABILITY_TRANQUILITY )
	{
		new iSkillLevel = SM_GetSkillLevel( id, ABILITY_TRANQUILITY )
		new param[2]
		param[0] = id
		param[1] = iSkillLevel
		PLAYER_CastSpell( id, ABILITY_TRANQUILITY, CAST_NORMAL, "_SPELL_Tranquility", param, sizeof(param) )
	}
}



//------------------------------------
// DRUID_TriggerUltimate
//
//------------------------------------
DRUID_TriggerUltimate( id, iSkillID )
{
	if( iSkillID == ULTIMATE_ENTANGLE )
	{
		PLAYER_CastSpell( id, ULTIMATE_ENTANGLE, CAST_SEARCH, "_SPELL_Entangle", _, _, CAST_SEARCH_OPPOSITE_TEAM )
	}
}




//------------------------------------
// DRUID_SkillsOffensive
//
//------------------------------------
public DRUID_SkillsOffensive( iAttacker, iVictim, iWeapon, &iDamage, iDamageType )
{
	new iSkillLevel
	
	// Trueshot Aura
	iSkillLevel = SM_GetSkillLevel( iAttacker, SKILL_TRUESHOT )
	if( iSkillLevel > 0 )
		DRUID_TrueshotAura( iSkillLevel, iAttacker, iVictim, iDamage, iDamageType )
}




//------------------------------------
// DRUID_SkillsDefensive
//
//------------------------------------
public DRUID_SkillsDefensive( iAttacker, iVictim, &iDamage, iWeapon, iDamageType )
{
	new iSkillLevel

	// Thorns Aura
	iSkillLevel = SM_GetSkillLevel( iVictim, SKILL_THORNS )
	if( iDamage > 0 && iSkillLevel > 0 && (iDamageType & (DMG_BULLET|DMG_SLASH)) )
	{
		new param[5]
		param[0] = iVictim
		param[1] = iAttacker
		param[2] = PlayerInfo[iVictim][PI_Hitgroup]
		param[3] = iSkillLevel
		param[4] = iDamage
		PLAYER_CastSpell( iVictim, SKILL_THORNS, CAST_PASSIVE, "_SPELL_ThornsAura", param, 5, CAST_IGNORE_MANA_COST )
	}

}



//------------------------------------
// DRUID_Quickness
//
//------------------------------------
bool:DRUID_Quickness( iVictim, iHitgroup )
{
	new iSkillLevel = SM_GetSkillLevel( iVictim, SKILL_QUICKNESS )
	if( iSkillLevel > 0 && random_float( 0.0, 1.0 ) <= p_quickness[iSkillLevel-1] )
	{
		new iGlowIntensity = random_num( 20, 50 )
		
		// Head shot
		if( iHitgroup == HIT_HEAD )
			iGlowIntensity += 250
		else if( iHitgroup == HIT_CHEST )
			iGlowIntensity += 75
		
		// Make the user glow!
		SHARED_Glow( iVictim, COLOR_RGB( 0, 0, iGlowIntensity ) )

		EFFECT_ScreenFade( iVictim, 0.25, 0.25, COLOR_RGBA(0, 0, 255, min(iGlowIntensity, 150)) )

		WCG_StatusText( iVictim, TXT_SKILL, HUD_SKILL, "You have evaded a shot!" )
		return true
	}
	return false
}




//------------------------------------
// DRUID_TrueshotAura
//
//------------------------------------
public DRUID_TrueshotAura( iSkillLevel, iAttacker, iVictim, &iDamage, iDamageType )
{
	static iTrueshotDamage

	if( !(iDamageType & DMG_BULLET) )
		return

	iTrueshotDamage = floatround( float( iDamage ) * p_trueshot[iSkillLevel-1] )
	iDamage += iTrueshotDamage

	// Make the user glow!
	SHARED_Glow( iVictim, COLOR_RGB( ( 2 * iTrueshotDamage ), 0, 0 ) )
}



//--------------------------------------------------------------------------------------------------------------------------
// ThornsAura


//------------------------------------
// _SPELL_ThornsAura
//
// PLAYER_CastSpell callback
//		param[0] = Caster ID
//		param[1] = Victim ID (player that will be hit by thornsaura)
//		param[2] = Hitgroup
//		param[3] = SkillLevel of thornsaura about to be casted
//		param[4] = Damage thornsaura will base calculations on
//------------------------------------
public _SPELL_ThornsAura( const param[5] )
{
	new id			= param[0]
	new iVictim		= param[1]
//	new iHitgroup	= param[2]
	new iSkillLevel	= param[3]
	new iDamage		= param[4]
	
	if( !is_user_alive(id) || !is_user_alive(iVictim) )
		return

	new iThornsDamage = floatround( float( iDamage ) * p_thorns[iSkillLevel-1] )

	if( iThornsDamage > 0 )
	{
		if( !PLAYER_CheckMagicHit( id, iVictim ) )
			return

		// Damage the user
		PLAYER_MagicDamage( iVictim, id, iThornsDamage, CSW_THORNS )

		// Make the user glow!
		SHARED_Glow( iVictim, COLOR_RGB( ( 3 * iThornsDamage ), 0, 0 ) )
		
		// Create a screen fade
		EFFECT_ScreenFade( iVictim, 0.25, 0.25, COLOR_RGBA(0, 0, 255, iThornsDamage) )
	}
}




//--------------------------------------------------------------------------------------------------------------------------
// Tranquility

#define TRANQUILITY_TIME 		15.0	// Total time in seconds the tranquility task will run
#define TRANQUILITY_FREQ 		0.5		// How long time in seconds between task repeats
#define TRANQUILITY_RANGE		500		// How many units tranquility will search for players
#define TRANQUILITY_COOLDOWN	60		// Time in seconds before tranquility is available again



//------------------------------------
// _Tranquility
//
// PLAYER_CastSpell callback
//		param[0] = Caster ID
//		param[1] = SkillLevel of the spell to be casted
//------------------------------------
public _SPELL_Tranquility( const param[] )
{
	static param2[6], vOrigin[3]
	
	new id = param[0]
	new iSkillLevel = param[1]
	
	if( !is_user_alive(id) || iSkillLevel <= 0 )
		return
	
	get_user_origin( id, vOrigin )

	param2[0] = vOrigin[0]
	param2[1] = vOrigin[1]
	param2[2] = vOrigin[2]
	param2[3] = id
	param2[4] = PlayerInfo[id][PI_TeamID]
	param2[5] = iSkillLevel
	
	_SPELL_Tranquility_Task( param2 )
}



//------------------------------------
// _Tranquility_Task
//
// Tranquility repeating task
//------------------------------------
public _SPELL_Tranquility_Task( param[6] )
{
	static Float:fCounter[33], Float:fScalar
	static id, vOrigin[3], team, iSkillLevel
	static i, vPosition[3], vTargetOrigin[3], iDistance, iTargetID

	new const Float:fStepping = 100.0 / (TRANQUILITY_TIME / TRANQUILITY_FREQ)


	id 			= param[3]
	vOrigin[0] 	= param[0]
	vOrigin[1] 	= param[1]
	vOrigin[2] 	= param[2]
	team		= param[4]
	iSkillLevel	= param[5]

	// If the task doesn't exists, it's the first time it runs
	if( !task_exists( TASK_TRANQUILITY + id ) )
	{
		fCounter[id] = 100.0

		// Play the tranquility sound
		emit_sound( id, CHAN_STATIC, g_szSounds[SOUND_TRANQUILITY], VOL_NORM, ATTN_NORM, 0, PITCH_NORM )
		
		new r = floatround( 96.0 / 5.0 * iSkillLevel )
		new g = floatround( 155.0 / 5.0 * iSkillLevel )
		new b = floatround( 255.0 / 5.0 * iSkillLevel )
		new radius = floatround( 65.0 / 5.0 * iSkillLevel )
		new life = floatround( 170.0 / 5.0 * iSkillLevel )
		
		Create_TE_DLIGHT( vOrigin, radius, r, g, b, life, 4 )

		// Start the repeating task job
		set_task( TRANQUILITY_FREQ, "_SPELL_Tranquility_Task", TASK_TRANQUILITY + id, param, sizeof(param), "a", \
					floatround((TRANQUILITY_TIME-TRANQUILITY_FREQ)/TRANQUILITY_FREQ) )
	}

	if( iSkillLevel >= 2 )
	{
		for( i = 0 ; i < floatround(1+fCounter[id]/12.0) ; i++ )
		{
			vPosition[0] = vOrigin[0] - random_num( -450, 450 )
			vPosition[1] = vOrigin[1] - random_num( -450, 450 )
			vPosition[2] = vOrigin[2] - random_num( -100, 100 )
			EFFECT_Implosion( 0, vPosition, 100, 5, random_num( 2, 20 ) )
		}
	}
	
	if( iSkillLevel == 5 )
	{
		for( i = 0 ; i < floatround(1+fCounter[id]/12.0) ; i++ )
		{
			vPosition[0] = vOrigin[0] - random_num( -450, 450 )
			vPosition[1] = vOrigin[1] - random_num( -450, 450 )
			vPosition[2] = vOrigin[2] - random_num( -100, 100 )
			Create_TE_EXPLOSION( vPosition, vPosition, g_spr_animglow01, random_num( 1, 4 ), 24, 4 )
		}
	}

	vPosition[0] = vOrigin[0]
	vPosition[1] = vOrigin[1]
	vPosition[2] = vOrigin[2] + TRANQUILITY_RANGE
	fScalar =  1.5 + (10.0 / iSkillLevel)
	Create_TE_BEAMCYLINDER( vOrigin, vOrigin, vPosition, g_spr_shockwave, 0, 0, 10, 55, 100, 188, 220, 255, 1 + floatround(fCounter[id]/fScalar), 0 )

	fCounter[id] -= fStepping
	
	if( fCounter[id] < 0.0 )
		fCounter[id] = 0.0

	new iHealAmount = p_tranquility[iSkillLevel-1]

	for( new i = 0 ; i < g_NumTeamPlayers[team] ; i++ )
	{
		iTargetID = g_SortedTeams[team][i]

		if( is_user_alive(iTargetID) )
		{
			get_user_origin( iTargetID, vTargetOrigin )
			iDistance = get_distance( vOrigin, vTargetOrigin )
	
			if( iDistance <= TRANQUILITY_RANGE )
				PLAYER_Heal( iTargetID, iHealAmount, id )
		}
	}
}



//--------------------------------------------------------------------------------------------------------------------------
// Entangle

#define	ENTANGLE_TIME		8.0


//------------------------------------
// _SPELL_Entangle
//
// PLAYER_CastSpell callback
//		param[0] = Caster ID
//		param[1] = Victim ID
//------------------------------------
public _SPELL_Entangle( const param[] )
{
	new iCasterID = param[0]
	new id = param[1]

	if( !PLAYER_CheckMagicHit( iCasterID, id ) )
	{
		client_print( iCasterID, print_chat, "Your Entangle Roots was resisted by %s.", PlayerInfo[id][PI_PlayerName] )
		client_print( id, print_chat, "You resisted %s's Entangle Roots.", PlayerInfo[iCasterID][PI_PlayerName] )
		client_cmd( iCasterID, "spk %s", g_szSounds[SOUND_DISPELL] )
		return
	}

	if( PlayerInfo[id][PI_IsImmobilized] )
	{
		client_print( iCasterID, print_chat, "%s Your Entangle Roots had no effect", g_MODclient )
		emit_sound( iCasterID, CHAN_STATIC, g_szSounds[SOUND_DISPELL], VOL_NORM, ATTN_NORM, 0, PITCH_NORM )
		return
	}

	// User is now stunned so we can't do any other stun abilities
	PlayerInfo[id][PI_IsImmobilized] = true

	// Set the speed of the enemy (this will auto-immobilize them)
	PLAYER_UpdateSpeed( id )
	
	// Reset the user's speed in ENTANGLE_TIME amount of time
	set_task( ENTANGLE_TIME, "SHARED_ResetMaxSpeed", TASK_RESETSPEED + id )

	// Get the user's origin
	new vOrigin[3]
	get_user_origin( id, vOrigin )

	// align near ground
	vOrigin[2] -= 34
	
	// Play the entangle sound
	emit_sound( id, CHAN_STATIC, g_szSounds[SOUND_ENTANGLINGSTART], VOL_NORM, ATTN_NORM, 0, PITCH_NORM )

	// Create the spiral effect
	EFFECT_BeamSpiral( vOrigin, 20, 64, 8, 4, g_spr_lgtning, ENTANGLE_TIME, 20, 2, COLOR_RGBA(10, 108, 23, 255) )

	new args[2]
	args[0] = iCasterID
	args[1] = id
	_SPELL_EntangleDamage( args )

	set_task( ENTANGLE_TIME - 0.5, "_SPELL_EntangleEnd", TASK_ALIVE_EFFECT + id )
}



//------------------------------------
// _SPELL_EntangleDamage
//
//------------------------------------
public _SPELL_EntangleDamage( param[] )
{
	new iAttacker	= param[0]
	new iVictim 	= param[1]	
	
	if( !is_user_alive( iVictim ) || !PlayerInfo[iVictim][PI_IsImmobilized] )
		return

	PLAYER_MagicDamage( iVictim, iAttacker, 5, CSW_ENTANGLE )

	set_task( 2.0, "_SPELL_EntangleDamage", TASK_ALIVE_EFFECT + iVictim, param, 2 )
}



//------------------------------------
// _SPELL_EntangleEnd
//
//------------------------------------
public _SPELL_EntangleEnd( id )
{
	id = GetTaskID( id, TASK_ALIVE_EFFECT )

	if( is_user_alive(id) && PlayerInfo[id][PI_IsImmobilized] )
		emit_sound( id, CHAN_STATIC, g_szSounds[SOUND_ENTANGLINGEND], VOL_NORM, ATTN_NORM, 0, PITCH_NORM )
}
